from django.shortcuts import render
import datetime
from web.forms.issues import IssuesModelForm, IssuesReplyModelForm, InviteModelForm
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
from web import models
from utils.pagination import Pagination
from django.utils.safestring import mark_safe
import json
from utils.encrypt import uid
from django.urls import reverse


class CheckFilter(object):
    def __init__(self, name, data_list, request):
        self.data_list = data_list
        self.request = request
        self.name = name

    def __iter__(self):
        for item in self.data_list:
            key = str(item[0])
            text = item[1]
            ck = ""
            value_list = self.request.GET.getlist(self.name)
            if key in value_list:
                ck = 'checked'
                value_list.remove(key)
            else:
                value_list.append(key)
            query_dict = self.request.GET.copy()
            query_dict._mutable = True
            query_dict.setlist(self.name, value_list)
            # 当页面数据只有一条可数的几个页面，跳转到page=1
            if 'page' in query_dict:
                query_dict.pop('page')
            # 当url中没有参数的时候，把？去掉
            param_url = query_dict.urlencode()
            if param_url:
                url = "{}?{}".format(self.request.path_info, param_url)
            else:
                url = self.request.path_info
            html = '<a class="cell" href="{url}"><input type="checkbox" {ck} /><label>{text}</label></a>'.format(
                url=url, ck=ck,
                text=text)
            yield mark_safe(html)


class SelectFilter(object):
    def __init__(self, name, data_list, request):
        self.data_list = data_list
        self.request = request
        self.name = name

    def __iter__(self):
        yield mark_safe("<select class='select2' multiple='multiple' style='width:100%;' >")
        for item in self.data_list:
            key = str(item[0])
            text = item[1]
            # 默认指派者被选中
            selected = ""
            value_list = self.request.GET.getlist(self.name)
            if key in value_list:
                selected = "selected"
                value_list.remove(key)
            else:
                value_list.append(key)

            query_dict = self.request.GET.copy()
            query_dict._mutable = True
            query_dict.setlist(self.name, value_list)
            # 当页面数据只有一条可数的几个页面，跳转到page=1
            if 'page' in query_dict:
                query_dict.pop('page')
            # 当url中没有参数的时候，把？去掉
            param_url = query_dict.urlencode()
            if param_url:
                url = "{}?{}".format(self.request.path_info, param_url)
            else:
                url = self.request.path_info
            html = "<option value={url} {selected}>{text}</option>".format(url=url, selected=selected, text=text)
            yield mark_safe(html)
        yield mark_safe("</select>")


def issues(request, project_id):
    if request.method == "GET":
        allow_filter_name = ['status', 'priority', 'issues_type', 'assign', 'attention']
        condition = {}
        for name in allow_filter_name:
            value_list = request.GET.getlist(name)
            if not value_list:
                continue
            condition["{}__in".format(name)] = value_list
        queryset = models.Issues.objects.filter(project_id=project_id).filter(**condition)  # 全部数据
        page_object = Pagination(
            current_page=request.GET.get("page"),
            all_count=queryset.count(),
            base_url=request.path_info,
            query_params=request.GET,
            per_page=10,

        )
        user_object_list = queryset[page_object.start:page_object.end]  # 切片
        form = IssuesModelForm(request)
        project_total_user = [(request.tracer.project.creator_id, request.tracer.project.creator.username)]
        project_join_user = models.ProjectUser.objects.filter(project_id=project_id).values_list('user_id',
                                                                                                 'user__username')
        project_total_user.extend(project_join_user)
        invite_form = InviteModelForm()
        context = {
            'form': form,
            'invite_form': invite_form,
            'user_object_list': user_object_list,
            'page': page_object.page_html(),
            'filter_list': [
                {'title': '问题类型', 'filter': CheckFilter('issues_type',
                                                        models.IssuesType.objects.filter(
                                                            project_id=project_id).values_list('id',
                                                                                               'title'),
                                                        request)},
                {'title': '状态', 'filter': CheckFilter('status', models.Issues.status_choices, request)},
                {'title': '优先级', 'filter': CheckFilter('priority', models.Issues.priority_choices, request)},
                {'title': '指派者', 'filter': SelectFilter('assign', project_total_user, request)},
                {'title': '关注者', 'filter': SelectFilter('attention', project_total_user, request)},
            ]

        }
        return render(request, 'personal_management/issues.html', context)
    form = IssuesModelForm(request, data=request.POST)
    if form.is_valid():
        print("123")
        form.instance.project = request.tracer.project
        form.instance.creator = request.tracer.user
        form.save()
        print("保存成功")
        return JsonResponse({'status': True})
    return JsonResponse({'status': False, 'error': form.errors})


def issues_detail(request, project_id, issues_id):
    issues_object = models.Issues.objects.filter(id=issues_id, project_id=project_id).first()
    form = IssuesModelForm(request, instance=issues_object)
    return render(request, 'personal_management/issues_detail.html', {'form': form, 'issues_object': issues_object})


@csrf_exempt
def issues_record(request, project_id, issues_id):
    if request.method == 'GET':
        """初始化问题操作记录"""
        reply_list = models.IssuesReply.objects.filter(issues_id=issues_id, issues__project=request.tracer.project)
        data_list = []
        for row in reply_list:
            data = {
                'id': row.id,
                'reply_type_text': row.get_reply_type_display(),
                'content': row.content,
                'creator': row.creator.username,
                'datetime': row.create_datetime.strftime("%Y-%m-%d %H:%M"),
                'parent_id': row.reply_id
            }
            data_list.append(data)
        return JsonResponse({'status': True, 'data': data_list})
    form = IssuesReplyModelForm(data=request.POST)

    if form.is_valid():
        form.instance.issues_id = issues_id
        form.instance.reply_type = 2
        form.instance.creator = request.tracer.user
        instance = form.save()
        info = {
            'id': instance.id,
            'reply_type_text': instance.get_reply_type_display(),
            'content': instance.content,
            'creator': instance.creator.username,
            'datetime': instance.create_datetime.strftime("%Y-%m-%d %H:%M"),
            'parent_id': instance.reply_id
        }

        return JsonResponse({'status': True, 'data': info})
    return JsonResponse({'status': False, 'error': form.errors})


@csrf_exempt
def issues_change(request, project_id, issues_id):
    issues_object = models.Issues.objects.filter(id=issues_id, project_id=project_id).first()
    post_dict = json.loads(request.body.decode('utf-8'))
    name = post_dict.get('name')
    value = post_dict.get('value')

    def create_object(content):
        new_object = models.IssuesReply.objects.create(
            reply_type=1,
            issues=issues_object,
            content=content,
            creator=request.tracer.user,
        )
        new_reply_dict = {
            'id': new_object.id,
            'reply_type_text': new_object.get_reply_type_display(),
            'content': new_object.content,
            'creator': new_object.creator.username,
            'datetime': new_object.create_datetime.strftime("%Y-%m-%d %H:%M"),
            'parent_id': new_object.reply_id
        }
        return new_reply_dict

    # 1、数据库字段的更新
    # 1.1 文本
    try:
        field_object = models.Issues._meta.get_field(name)
        if name in ['subject', 'desc', 'start_time', 'end_time']:
            if not value:
                if not field_object.null:
                    return JsonResponse({'status': False, 'error': "您选择的值不能为空"})
                setattr(issues_object, name, None)
                issues_object.save()
                change_record = "{}更新为{}".format(field_object.verbose_name, name)
            else:
                setattr(issues_object, name, value)
                issues_object.save()
                change_record = "{}更新为{}".format(field_object.verbose_name, value)

            return JsonResponse({'status': True, 'data': create_object(change_record)})
        # 1.2 FK字段
        if name in ['issues_type', 'module', 'assign', 'parent']:
            if not value:
                if not field_object.null:
                    return JsonResponse({'status': False, 'error': "您选择的值不能为空"})
                setattr(issues_object, name, None)
                issues_object.save()
                change_record = "{}更新为空".format(field_object.verbose_name)
            else:
                if name == 'assign':
                    if value == str(request.tracer.project.creator_id):
                        instance = request.tracer.project.creator
                    else:
                        project_user = models.ProjectUser.objects.filter(project_id=project_id, user_id=value).first()
                        if project_user:
                            instance = project_user.user
                        else:
                            instance = None
                    if not instance:
                        return JsonResponse({'status': False, 'error': "您选择的值不存在"})
                    setattr(issues_object, name, instance)
                    issues_object.save()
                    change_record = "{}更新为{}".format(field_object.verbose_name, str(instance))
                else:
                    # 这里还要找到关联下面的表
                    instance = field_object.remote_field.model.objects.filter(id=value, project_id=project_id).first()
                    if not instance:
                        return JsonResponse({'status': False, 'error': "您选择的值不存在"})
                    setattr(issues_object, name, instance)
                    issues_object.save()
                    change_record = "{}更新为{}".format(field_object.verbose_name, str(instance))
            return JsonResponse({'status': True, 'data': create_object(change_record)})
        # 1.3 choices字段
        if name in ['priority', 'status', 'mode']:
            selected_text = None
            for key, text in field_object.choices:
                if str(key) == value:
                    selected_text = text
            if not selected_text:
                return JsonResponse({'status': False, 'error': "您选择的值不存在"})
            setattr(issues_object, name, value)
            issues_object.save()
            change_record = "{}更新为{}".format(field_object.verbose_name, selected_text)
            return JsonResponse({'status': True, 'data': create_object(change_record)})
        # 1.4 M2M字段
        if name == "attention":
            if not isinstance(value, list):
                return JsonResponse({'status': False, "error": "数据格式错误"})
            if not value:
                issues_object.attention.set(value)
                issues_object.save()
                change_record = "{}更新为空".format(field_object.verbose_name)
            else:
                # 获取项目所有的创建者{id:username}
                user_dict = {str(request.tracer.project.creator_id): request.tracer.project.creator.username}
                # 获取当前项目的所有成员
                project_user_list = models.ProjectUser.objects.filter(project_id=project_id)
                for item in project_user_list:
                    user_dict[str(item.user_id)] = item.user.username
                username_list = []
                for user_id in value:
                    username = user_dict.get(str(user_id))
                    if not username:
                        return JsonResponse({'status': False, "error": "用户不存在，请重新设置"})
                    username_list.append(username)
                issues_object.attention.set(value)
                issues_object.save()
                change_record = "{}更新为{}".format(field_object.verbose_name, ','.join(username_list))
            return JsonResponse({'status': True, 'data': create_object(change_record)})
    except None as e:
        pass
        # 2. 生成记录

    return JsonResponse({'status': False, 'error': '请离开'})


def invite_url(request, project_id):
    pass
    """生成邀请码"""
    """表单验证"""
    form = InviteModelForm(data=request.POST)
    if form.is_valid():
        """
        1.创建随机的邀请码
        2.邀请码保存到数据库
        3.限制：只能创建者才能邀请
        """
        if request.tracer.user != request.tracer.project.creator:
            form.add_error('period', '无权限创建邀请码')
            return JsonResponse({'status': False, 'error': form.errors})
        random_invite_code = uid(request.tracer.user.mobile_phone)
        # 把这个码保存到数据库
        form.instance.project = request.tracer.project
        form.instance.code = random_invite_code
        form.instance.creator = request.tracer.user
        form.save()
        # 将验证码返回给前端，前端页面上在展示出来
        # 反向生成url_path /invite_join/xxxx/xxxx
        url_path = reverse('websass:invite_join', kwargs={'code': random_invite_code})
        url = "{scheme}://{host}{path}".format(scheme=request.scheme, host=request.get_host(), path=url_path)
        return JsonResponse({'status': True, 'data': url})
    return JsonResponse({'status': False, 'error': form.errors})


def invite_join(request, code):
    current_time = datetime.datetime.now()
    """访问邀请码"""
    """看一下邀请码存不存在"""
    invite_object = models.ProjectInvite.objects.filter(code=code).first()
    if not invite_object:
        return render(request, 'personal_management/invite_join.html', {'error': '邀请码不存在'})
    """是否是创建者"""
    if invite_object.project.creator == request.tracer.user:
        return render(request, 'personal_management/invite_join.html', {'error': '创建者无需加入项目'})
    """是否已经加入项目"""
    exists = models.ProjectUser.objects.filter(project=invite_object.project, user=request.tracer.user).exists()
    if exists:
        return render(request, 'personal_management/invite_join.html', {'error': '已加入项目无需再加入'})
    """允许最多的成员"""
    # max_member = request.tracer.price_policy.p_member
    # 是否套餐已过期使用免费的额度
    max_transaction = models.Transaction.objects.filter(t_user=invite_object.project.creator).order_by('-id').first()
    if max_transaction.t_price.category == 1:
        max_member = max_transaction.t_price.p_member
    else:
        if max_transaction.t_end < current_time:
            free_object = models.CommodityPrices.objects.filter(category=1).first()
            max_member = free_object.p_member
        else:
            max_member = max_transaction.t_price.p_member
    """目前最多的成员（创建者&参于者）"""
    current_member = models.ProjectUser.objects.filter(project=invite_object.project).count()
    current_member += 1
    if current_member >= max_member:
        return render(request, 'personal_management/invite_join.html', {'error': '项目成员超限，请升级套餐'})

    limit_datetime = invite_object.create_datetime + datetime.timedelta(minutes=invite_object.period)
    if current_time > limit_datetime:
        return render(request, 'personal_management/invite_join.html', {'error': '邀请码已过期'})
    # 邀请的数量限制
    if invite_object.count:
        if invite_object.user_count >= invite_object.count:
            return render(request, 'personal_management/invite_join.html', {'error': '邀请成员已满'})
        invite_object.user_count += 1
        invite_object.save()
    # 无数量限制
    models.ProjectUser.objects.create(user=request.tracer.user, project=invite_object)
    invite_object.project.join_count += 1
    invite_object.project.save()
    return render(request, 'personal_management/invite_join.html', {'project': invite_object.project})
